package config

import (
	"bufio"
	"encoding/json"
	"os"
	"reflect"
	"strings"
)

type Config struct {
	AppName                string         `json:"app_name"`
	AppModel               string         `json:"app_model"`
	AppHost                string         `json:"app_host"`
	AppPort                string         `json:"app_port"`
	Debug                  bool           `json:"debug"`
	ReloadConfigPrivateKey string         `json:"reload_config_private_key"`
	Database               DatabaseConfig `json:"database"`
	RedisConfig            RedisConfig    `json:"redis"`
	JwtConfig              JwtConfig      `json:"jwt"`
	Elasticsearch          Elasticsearch  `json:"elasticsearch"`
	DataSources            DataSources    `json:"dataSources"`
	FullDatabase           DatabaseConfig `json:"full_database"`
	Rabbit                 Rabbit         `json:"rabbit"`
	UsernameMappingNumber  uint32         `json:"username_mapping_number"`
	OpenidMappingNumber    uint32         `json:"openid_mapping_number"`
	//=======
	//	AppName                string             `json:"app_name"`
	//	AppModel               string             `json:"app_model"`
	//	AppHost                string             `json:"app_host"`
	//	AppPort                string             `json:"app_port"`
	//	Debug                  bool               `json:"debug"`
	//	ReloadConfigPrivateKey string             `json:"reload_config_private_key"`
	//	SourceData             [][]DatabaseConfig `json:"source_data"`
	//	Database               DatabaseConfig     `json:"database"`
	//	RedisConfig            RedisConfig        `json:"redis"`
	//	JwtConfig              JwtConfig          `json:"jwt"`
	//	Elasticsearch          Elasticsearch      `json:"elasticsearch"`
	//	DataSources   DataSources    `json:"dataSources"`
	//	Rabbit                 Rabbit             `json:"rabbit"`
	//>>>>>>> d1607ac61504892315806ef9273ef8b132962872
}

type DatabaseConfig struct {
	Driver   string `json:"driver"`
	User     string `json:"user"`
	Password string `json:"password"`
	Host     string `json:"host"`
	Port     string `json:"port"`
	DbName   string `json:"db_name"`
	Charset  string `json:"charset"`
	ShowSql  bool   `json:"show_sql"`
}

type SourcesDatabaseConfig struct {
	DataCenterId int    `json:"data_center_id"`
	WorkerId     int    `json:"worker_id"`
	Driver       string `json:"driver"`
	User         string `json:"user"`
	Password     string `json:"password"`
	Host         string `json:"host"`
	Port         string `json:"port"`
	DbName       string `json:"db_name"`
	Charset      string `json:"charset"`
	ShowSql      bool   `json:"show_sql"`
}

type DataSources []DataCenter

type DataCenter []DataWorker

type DataWorker SourcesDatabaseConfig

// RedisConfig Redis属性定义
type RedisConfig struct {
	Addr     string `json:"addr"`
	Port     string `json:"port"`
	Password string `json:"password"`
	Db       int    `json:"db"`
}

// JwtConfig Jwt配置映射
type JwtConfig struct {
	PrivateKey string `json:"private_key"`
}

// Elasticsearch Elasticsearch配置映射
type Elasticsearch struct {
	Host string `json:"host"`
}

// Rabbit Rabbit配置映射
type Rabbit struct {
	Uri string `json:"uri"`
}

// GetConfig 方法或者变量首字母大写, 表示对外可见
func GetConfig(key string) interface{} {
	keys := strings.Split(key, ".")
	var ref interface{}
	ref = *cfg
	for ki := 0; ki < len(keys); ki++ {
		var find bool
		for i := 0; i < reflect.ValueOf(ref).NumField(); i++ {
			if reflect.TypeOf(ref).Field(i).Tag.Get("json") == keys[ki] {
				ref = reflect.ValueOf(ref).Field(i).Interface()
				find = true
				if ki == len(keys)-1 {
					break
				}
			}
		}
		if find == false {
			ref = nil
			break
		}
	}

	return ref
}

// 全局变量 对外不可见
var cfg *Config = nil

func ParseConfig(path string) (*Config, error) {
	file, err := os.Open(path)
	defer file.Close()

	if err != nil {
		panic(err)
	}
	reader := bufio.NewReader(file)
	decoder := json.NewDecoder(reader)
	if err = decoder.Decode(&cfg); err != nil {
		return nil, err
	}
	return cfg, nil
}
